#pragma once 

#include<iostream>
#include<vector>
#include<pthread.h>
#include<semaphore.h>

#define NUM 5
using namespace std;
template<class T>
class RingQueue{
 private:
   void P(sem_t &s)
   {
     sem_wait(&s);
   }


   void V(sem_t &s)
   {
     sem_post(&s);
   }
  private:
    vector<T> q;
    int cap;
    sem_t blank_sem;
    sem_t data_sem;
    int c_pos;//消费位置
    int p_pos;//生产位置
  public:
    RingQueue(int _cap=NUM): cap(_cap),c_pos(0),p_pos(0)
    {
     q.resize(cap);
     sem_init(&blank_sem,0,cap);//格子是有的满的
     sem_init(&data_sem,0,0);//数据还没有生产
     
    }
    //生产者调用，生产数据
    void push(const T& in)//先运行
    {
        P(blank_sem);
        q[p_pos]=in;
        V(data_sem);
        p_pos++;
        p_pos%=cap;
    }

    void pop(T &out)
    {
      P(data_sem);
      out=q[c_pos];
      V(blank_sem);
      c_pos++;
      c_pos%=cap;
    }
    ~RingQueue()
    {
    sem_destroy(&blank_sem);
    sem_destroy(&data_sem);
    }
};
